[LINUX] Make xen /dev/mem aware of IA64 to use X.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 22 Nov 2006 10:23:14 +0000 (10:23 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 22 Nov 2006 10:23:14 +0000 (10:23 +0000)
The original /dev/mem (linux/drivers/char/mem.c) is aware of IA64
specific issues. On the other hand paravirtualized /dev/mem
(linux-2.6-xen-sparse/drivers/xen/char/mem.c) is simplifed not to be
aware of IA64. This patch makes it IA64-aware to use X on domain0/IA64.
With this patch and ia64-specific patches, X server can boot on domain0/IA64.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
linux-2.6-xen-sparse/drivers/xen/char/mem.c
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/io.h
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/io.h

index 6576135c990f02b7c84d8c56074245586f9d9845..ac85c8dbb220a28326602989d492f086bb03d8fd 100644 (file)
 #include <asm/io.h>
 #include <asm/hypervisor.h>
 
-static inline int uncached_access(struct file *file)
+#ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE
+static inline int valid_phys_addr_range(unsigned long addr, size_t *count)
 {
-       if (file->f_flags & O_SYNC)
-               return 1;
-       /* Xen sets correct MTRR type on non-RAM for us. */
-       return 0;
+       return 1;
 }
+#endif
 
 /*
  * This funcion reads the *physical* memory. The f_pos points directly to the 
@@ -47,6 +46,9 @@ static ssize_t read_mem(struct file * file, char __user * buf,
        ssize_t read = 0, sz;
        void __iomem *v;
 
+       if (!valid_phys_addr_range(p, &count))
+               return -EFAULT;
+
        while (count > 0) {
                /*
                 * Handle first page in case it's not aligned
@@ -58,13 +60,15 @@ static ssize_t read_mem(struct file * file, char __user * buf,
 
                sz = min_t(unsigned long, sz, count);
 
-               if ((v = ioremap(p, sz)) == NULL) {
+               v = xlate_dev_mem_ptr(p, sz);
+               if (IS_ERR(v) || v == NULL) {
                        /*
-                        * Some programs (e.g., dmidecode) groove off into weird RAM
-                        * areas where no tables can possibly exist (because Xen will
-                        * have stomped on them!). These programs get rather upset if
-                        * we let them know that Xen failed their access, so we fake
-                        * out a read of all zeroes. :-)
+                        * Some programs (e.g., dmidecode) groove off into
+                        * weird RAM areas where no tables can possibly exist
+                        * (because Xen will have stomped on them!). These
+                        * programs get rather upset if we let them know that
+                        * Xen failed their access, so we fake out a read of
+                        * all zeroes.
                         */
                        if (clear_user(buf, count))
                                return -EFAULT;
@@ -73,7 +77,7 @@ static ssize_t read_mem(struct file * file, char __user * buf,
                }
 
                ignored = copy_to_user(buf, v, sz);
-               iounmap(v);
+               xlate_dev_mem_ptr_unmap(v);
                if (ignored)
                        return -EFAULT;
                buf += sz;
@@ -93,6 +97,9 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
        ssize_t written = 0, sz;
        void __iomem *v;
 
+       if (!valid_phys_addr_range(p, &count))
+               return -EFAULT;
+
        while (count > 0) {
                /*
                 * Handle first page in case it's not aligned
@@ -104,11 +111,17 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
 
                sz = min_t(unsigned long, sz, count);
 
-               if ((v = ioremap(p, sz)) == NULL)
+               v = xlate_dev_mem_ptr(p, sz);
+               if (v == NULL)
                        break;
+               if (IS_ERR(v)) {
+                       if (written == 0)
+                               return PTR_ERR(v);
+                       break;
+               }
 
                ignored = copy_from_user(v, buf, sz);
-               iounmap(v);
+               xlate_dev_mem_ptr_unmap(v);
                if (ignored) {
                        written += sz - ignored;
                        if (written)
@@ -125,6 +138,15 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
        return written;
 }
 
+#ifndef ARCH_HAS_DEV_MEM_MMAP_MEM
+static inline int uncached_access(struct file *file)
+{
+       if (file->f_flags & O_SYNC)
+               return 1;
+       /* Xen sets correct MTRR type on non-RAM for us. */
+       return 0;
+}
+
 static int mmap_mem(struct file * file, struct vm_area_struct * vma)
 {
        size_t size = vma->vm_end - vma->vm_start;
@@ -136,6 +158,7 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
        return direct_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
                                      size, vma->vm_page_prot, DOMID_IO);
 }
+#endif
 
 /*
  * The memory devices use the full 32/64 bits of the offset, and so we cannot
index 7f9b7cdd36ff64919ecff9e4f0fa08798f5fd3d3..ed5203a5731114c88dc125fd1178726da606ebe3 100644 (file)
@@ -54,7 +54,8 @@
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
  * access
  */
-#define xlate_dev_mem_ptr(p)   __va(p)
+#define xlate_dev_mem_ptr(p, sz)       ioremap(p, sz)
+#define xlate_dev_mem_ptr_unmap(p)     iounmap(p)
 
 /*
  * Convert a virtual cached pointer to an uncached pointer
index 1ae9c89ba93ffbfa95a0c309c0137992e238517f..4d13b1b9c77c87497a7a87a6ef41fda50b2564f8 100644 (file)
@@ -346,7 +346,8 @@ extern int iommu_bio_merge;
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
  * access
  */
-#define xlate_dev_mem_ptr(p)   __va(p)
+#define xlate_dev_mem_ptr(p, sz)       ioremap(p, sz)
+#define xlate_dev_mem_ptr_unmap(p)     iounmap(p)
 
 /*
  * Convert a virtual cached pointer to an uncached pointer